﻿using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using StarsAdmin.Application.Dict.Dtos;
using StarsAdmin.Application.Role.Dtos;
using StarsAdmin.Core.Cache;
using StarsAdmin.Core.Consts;
using StarsAdmin.Core.DB.Entities;
using StarsAdmin.Core.Exceptions;
using StarsAdmin.Core.Extensions;
using StarsAdmin.Core.Models;
using StarsAdmin.Repository.Address;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace StarsAdmin.Application.Dict.Services
{
    public class DictService : IDictService
    {
        private readonly IMapper _mapper;
        private readonly ICacheService _cache;
        private readonly IDictRepository _dictRepository;

        public DictService(IMapper mapper, ICacheService cacheService, IDictRepository dictRepository)
        {
            _mapper = mapper;
            _cache = cacheService;
            _dictRepository = dictRepository;
        }

        public async Task<List<DictDto>> GetAllAsync(BaseQueryInput input)
        {
            var result = await _dictRepository.GetAll().AsNoTracking()
                                 .WhereIf(input != null && input.QueryConditions.Any(), input.QueryConditions)
                                 .OrderByIf(input != null && input.Sort != null, input.Sort, input.Order != false)
                                 .Include(e => e.DictType)
                                 .ToListAsync();
            return _mapper.Map<List<DictDto>>(result);
        }

        public async Task<Page<DictDto>> GetPageAsync(PageQueryInput input)
        {
            var result = await _dictRepository.GetAll().AsNoTracking()
                         .WhereIf(input != null && input.QueryConditions.Any(), input.QueryConditions)
                         .OrderByIf(input != null && input.Sort != null, input.Sort, input.Order != false)
                         .Include(e => e.DictType)
                         .ToPageListAsync(input.CurrentPage, input.PageSize);
            return _mapper.Map<Page<DictDto>>(result);
        }

        public async Task<DictDto?> GetByIdAsync(long id)
        {
            var result = await _dictRepository.GetById(id).Include(e => e.DictType).FirstOrDefaultAsync();
            return _mapper.Map<DictDto>(result);
        }

        public async Task<List<DictDto>> GetByIdsAsync(long[] ids)
        {
            var result = await _dictRepository.GetByIds(ids).Include(e => e.DictType).ToListAsync();
            return _mapper.Map<List<DictDto>>(result);
        }

        public async Task<FileContentResult?> ExportAsync(long[] ids)
        {
            var export = await _dictRepository.GetByIds(ids).Include(e => e.DictType).ToListAsync();
            return await _mapper.Map<List<ExportDictDto>>(export).ToExcelAsync("数据字典");
        }

        public async Task<bool> AddAsync(AddDictInput input)
        {
            var entity = _mapper.Map<DictEntity>(input);
            var result = await _dictRepository.AddAndSaveAsync(entity);
            if (result)
            {
                await _cache.RemoveAsync(CacheKeyConst.DictCacheKey);
            }
            return result;
        }

        public async Task<bool> UpdateAsync(UpdateDictInput input)
        {
            var dict = await _dictRepository.GetByIdAsync(input.Id);
            if (dict == null)
            {
                throw new NotFoundException("未找到指定的字典数据。");
            }
            var entity = _mapper.Map(input, dict);
            var result = await _dictRepository.UpdateAndSaveAsync(entity);
            if (result)
            {
                await _cache.RemoveAsync(CacheKeyConst.DictCacheKey);
            }
            return result;
        }

        public async Task<bool> DeleteAsync(long id)
        {
            var entity = await _dictRepository.GetByIdAsync(id);
            if (entity == null)
            {
                throw new NotFoundException("未找到指定的字典数据。");
            }
            var result = await _dictRepository.DeleteAndSaveAsync(entity.Id);
            if (result)
            {
                await _cache.RemoveAsync(CacheKeyConst.DictCacheKey);
            }
            return result;
        }

        public async Task<bool> BatchDeleteAsync(long[] ids)
        {
            var entities = await _dictRepository.GetByIdsAsync(ids);
            if (entities == null || entities.Count() < 1)
            {
                throw new NotFoundException("未找到指定的字典数据。");
            }
            var result = await _dictRepository.DeleteRangeAndSaveAsync(ids);
            if (result)
            {
                await _cache.RemoveAsync(CacheKeyConst.DictCacheKey);
            }
            return result;
        }
    }
}